package com.smart.community.region.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import javax.validation.Valid;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.smart.community.commons.annotation.ApiLog;
import com.smart.community.commons.enums.ApiLogOperationType;
import com.smart.community.commons.result.Result;
import com.smart.community.commons.dto.FileInfoDTO;
import com.smart.community.commons.utils.FileInfoUtils;
import com.smart.community.region.dto.ShopDTO;
import com.smart.community.region.entity.Shop;
import com.smart.community.region.service.IShopService;
import com.smart.community.region.vo.ShopVO;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;

/**
 * 店铺管理控制器
 * 
 * @author Wu.Liang
 * @version 1.0.0
 * @since 2025-09-30
 */
@Slf4j
@RestController
@RequestMapping("/region/shop")
@Tag(name = "店铺管理", description = "店铺相关接口")
public class ShopController {
    
    @Autowired
    private IShopService shopService;
    
    /**
     * 分页查询店铺列表
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
     * 遵循《系统状态枚举权威标准声明.md》状态枚举规范
     */
    @GetMapping("/page")
    @Operation(summary = "分页查询店铺列表", description = "根据条件分页查询店铺列表")
    public Result<IPage<ShopVO>> getShopPage(@Parameter(description = "当前页", example = "1") @RequestParam(defaultValue = "1") Integer current,
                                             @Parameter(description = "每页大小", example = "10") @RequestParam(defaultValue = "10") Integer size,
                                             @Parameter(description = "店铺名称") @RequestParam(required = false) String shopName,
                                             @Parameter(description = "店铺编码") @RequestParam(required = false) String shopCode,
                                             @Parameter(description = "店铺类型") @RequestParam(required = false) Integer shopType,
                                             @Parameter(description = "社区ID") @RequestParam(required = false) Long communityId,
                                             @Parameter(description = "楼栋ID") @RequestParam(required = false) Long buildingId,
                                             @Parameter(description = "单元ID") @RequestParam(required = false) Long unitId,
                                             @Parameter(description = "房间号") @RequestParam(required = false) String roomNumber,
                                             @Parameter(description = "联系人") @RequestParam(required = false) String contactPerson,
                                             @Parameter(description = "联系电话") @RequestParam(required = false) String contactPhone,
                                             @Parameter(description = "状态") @RequestParam(required = false) Integer status,
                                             @Parameter(description = "最小面积") @RequestParam(required = false) java.math.BigDecimal minArea,
                                             @Parameter(description = "最大面积") @RequestParam(required = false) java.math.BigDecimal maxArea,
                                             @Parameter(description = "最小租金") @RequestParam(required = false) java.math.BigDecimal minRentPrice,
                                             @Parameter(description = "最大租金") @RequestParam(required = false) java.math.BigDecimal maxRentPrice) {
        try {
            log.info("分页查询店铺列表，当前页：{}，每页大小：{}，店铺名称：{}，店铺编码：{}，店铺类型：{}，社区ID：{}，楼栋ID：{}，单元ID：{}，房间号：{}，联系人：{}，联系电话：{}，状态：{}，面积范围：{}-{}，租金范围：{}-{}", 
                    current, size, shopName, shopCode, shopType, communityId, buildingId, unitId, roomNumber, contactPerson, contactPhone, status, minArea, maxArea, minRentPrice, maxRentPrice);
            
            // 调用Service查询
            IPage<ShopVO> shopPage = shopService.getShopPage(new Page<>(current, size), communityId, shopType, shopName, shopCode, buildingId, unitId, roomNumber, contactPerson, contactPhone, status, minArea, maxArea, minRentPrice, maxRentPrice);
            
            // 处理图片信息
            if (shopPage != null && shopPage.getRecords() != null) {
                for (ShopVO shopVO : shopPage.getRecords()) {
                    processImageInfo(shopVO);
                }
            }
            
            log.info("分页查询店铺列表成功，总记录数：{}", shopPage != null ? shopPage.getTotal() : 0);
            return Result.success("查询成功", shopPage);
        } catch (Exception e) {
            log.error("分页查询店铺列表失败", e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }
    
    /**
     * 根据ID查询店铺详情
     */
    @GetMapping("/{id}")
    @Operation(summary = "查询店铺详情", description = "根据ID查询店铺详情")
    public Result<ShopVO> getShopById(@Parameter(description = "店铺ID", example = "1") @PathVariable Long id) {
        try {
            log.info("查询店铺详情，ID：{}", id);
            
            // 参数校验
            if (id == null || id <= 0) {
                return Result.fail("店铺ID必须大于0");
            }
            
            // 调用Service查询
            Shop shop = shopService.getById(id);
            if (shop == null) {
                return Result.fail("店铺不存在");
            }
            
            // 转换为VO
            ShopVO vo = convertToVO(shop);
            
            log.info("查询店铺详情成功，ID：{}", id);
            return Result.success("查询成功", vo);
        } catch (Exception e) {
            log.error("查询店铺详情失败，ID：{}", id, e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }
    
    /**
     * 新增店铺
     */
    @PostMapping
    @ApiLog(
        logTitle = "新增店铺",
        logType = 2,
        moduleName = "店铺管理",
        operationType = ApiLogOperationType.ADD
    )
    @Operation(summary = "新增店铺", description = "新增店铺信息")
    public Result<Long> createShop(@Valid @RequestBody ShopDTO dto) {
        try {
            log.info("新增店铺，店铺名称：{}", dto.getShopName());
            
            // 参数校验
            if (!StringUtils.hasText(dto.getShopName())) {
                return Result.fail("店铺名称不能为空");
            }
            if (dto.getShopType() == null) {
                return Result.fail("店铺类型不能为空");
            }
            if (dto.getCommunityId() == null) {
                return Result.fail("所属社区不能为空");
            }
            
            // 转换为Entity
            Shop shop = convertToEntity(dto);
            
            // 调用Service保存
            Long shopId = shopService.createShop(shop);
            if (shopId == null) {
                return Result.fail("新增店铺失败");
            }
            
            log.info("新增店铺成功，ID：{}", shopId);
            return Result.success("新增成功", shopId);
        } catch (Exception e) {
            log.error("新增店铺失败", e);
            return Result.fail("新增失败：" + e.getMessage());
        }
    }
    
    /**
     * 更新店铺
     */
    @PutMapping("/{id}")
    @ApiLog(
        logTitle = "更新店铺",
        logType = 2,
        moduleName = "店铺管理",
        operationType = ApiLogOperationType.UPDATE
    )
    @Operation(summary = "更新店铺", description = "更新店铺信息")
    public Result<Void> updateShop(@Parameter(description = "店铺ID", example = "1") @PathVariable Long id,
                                   @Valid @RequestBody ShopDTO dto) {
        try {
            log.info("更新店铺，ID：{}，店铺名称：{}", id, dto.getShopName());
            
            // 参数校验
            if (id == null || id <= 0) {
                return Result.fail("店铺ID必须大于0");
            }
            if (!StringUtils.hasText(dto.getShopName())) {
                return Result.fail("店铺名称不能为空");
            }
            if (dto.getShopType() == null) {
                return Result.fail("店铺类型不能为空");
            }
            if (dto.getCommunityId() == null) {
                return Result.fail("所属社区不能为空");
            }
            
            // 设置ID
            dto.setId(id);
            
            // 转换为Entity
            Shop shop = convertToEntityForUpdate(dto);
            
            // 调用Service更新
            Boolean success = shopService.updateShop(shop);
            if (!success) {
                return Result.fail("更新店铺失败");
            }
            
            log.info("更新店铺成功，ID：{}", id);
            return Result.success("更新成功");
        } catch (Exception e) {
            log.error("更新店铺失败，ID：{}", id, e);
            return Result.fail("更新失败：" + e.getMessage());
        }
    }
    
    /**
     * 删除店铺
     */
    @DeleteMapping("/{id}")
    @ApiLog(
        logTitle = "删除店铺",
        logType = 2,
        moduleName = "店铺管理",
        operationType = ApiLogOperationType.DELETE
    )
    @Operation(summary = "删除店铺", description = "根据ID删除店铺")
    public Result<Void> deleteShop(@Parameter(description = "店铺ID", example = "1") @PathVariable Long id) {
        try {
            log.info("删除店铺，ID：{}", id);
            
            // 参数校验
            if (id == null || id <= 0) {
                return Result.fail("店铺ID必须大于0");
            }
            
            // 调用Service删除
            Boolean success = shopService.deleteShop(id);
            if (!success) {
                return Result.fail("删除店铺失败");
            }
            
            log.info("删除店铺成功，ID：{}", id);
            return Result.success("删除成功");
        } catch (Exception e) {
            log.error("删除店铺失败，ID：{}", id, e);
            return Result.fail("删除失败：" + e.getMessage());
        }
    }
    
    /**
     * 批量删除店铺
     */
    @DeleteMapping("/batch")
    @ApiLog(
        logTitle = "批量删除店铺",
        logType = 2,
        moduleName = "店铺管理",
        operationType = ApiLogOperationType.DELETE
    )
    @Operation(summary = "批量删除店铺", description = "根据ID列表批量删除店铺")
    public Result<Void> batchDeleteShops(@RequestBody List<Long> ids) {
        try {
            log.info("批量删除店铺，ID列表：{}", ids);
            
            // 参数校验
            if (ids == null || ids.isEmpty()) {
                return Result.fail("店铺ID列表不能为空");
            }
            
            // 调用Service批量删除
            Boolean success = shopService.batchDeleteShop(ids);
            if (!success) {
                return Result.fail("批量删除店铺失败");
            }
            
            log.info("批量删除店铺成功，删除数量：{}", ids.size());
            return Result.success("批量删除成功");
        } catch (Exception e) {
            log.error("批量删除店铺失败，ID列表：{}", ids, e);
            return Result.fail("批量删除失败：" + e.getMessage());
        }
    }
    
    /**
     * 更新店铺图片
     */
    @PutMapping("/{id}/images")
    @ApiLog(
        logTitle = "更新店铺图片",
        logType = 2,
        moduleName = "店铺管理",
        operationType = ApiLogOperationType.UPDATE
    )
    @Operation(summary = "更新店铺图片", description = "更新店铺的图片信息")
    public Result<Void> updateShopImages(@Parameter(description = "店铺ID", example = "1") @PathVariable Long id,
                                         @RequestBody List<FileInfoDTO> imageInfoList) {
        try {
            log.info("更新店铺图片，店铺ID：{}，图片数量：{}", id, imageInfoList.size());
            
            // 参数校验
            if (id == null || id <= 0) {
                return Result.fail("店铺ID必须大于0");
            }
            
            // 获取店铺信息
            Shop shop = shopService.getById(id);
            if (shop == null) {
                return Result.fail("店铺不存在");
            }
            
            // 更新图片信息
            shop.setImageInfoList(imageInfoList);
            
            // 调用Service更新
            Boolean success = shopService.updateShop(shop);
            if (!success) {
                return Result.fail("更新店铺图片失败");
            }
            
            log.info("更新店铺图片成功，店铺ID：{}，图片数量：{}", id, imageInfoList.size());
            return Result.success("更新成功");
        } catch (Exception e) {
            log.error("更新店铺图片失败，店铺ID：{}", id, e);
            return Result.fail("更新失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取店铺图片列表
     */
    @GetMapping("/{id}/images")
    @Operation(summary = "获取店铺图片列表", description = "根据店铺ID获取图片列表")
    public Result<List<FileInfoDTO>> getShopImages(@Parameter(description = "店铺ID", example = "1") @PathVariable Long id) {
        try {
            log.info("获取店铺图片列表，店铺ID：{}", id);
            
            // 参数校验
            if (id == null || id <= 0) {
                return Result.fail("店铺ID必须大于0");
            }
            
            // 获取店铺信息
            Shop shop = shopService.getById(id);
            if (shop == null) {
                return Result.fail("店铺不存在");
            }
            
            // 获取图片信息列表
            List<FileInfoDTO> imageInfoList = shop.getImageInfoList();
            
            log.info("获取店铺图片列表成功，店铺ID：{}，图片数量：{}", id, imageInfoList.size());
            return Result.success("查询成功", imageInfoList);
        } catch (Exception e) {
            log.error("获取店铺图片列表失败，店铺ID：{}", id, e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }
    
    // ==================== 辅助方法 ====================
    
    /**
     * 转换为VO
     */
    private ShopVO convertToVO(Shop shop) {
        if (shop == null) {
            return null;
        }
        
        ShopVO vo = new ShopVO();
        BeanUtils.copyProperties(shop, vo);
        
        // 设置图片信息
        vo.setImageInfoList(shop.getImageInfoList());
        vo.setImageUrls(shop.getImageUrls());
        vo.setFirstImageUrl(shop.getFirstImageUrl());
        vo.setImageCount(shop.getImageCount());
        
        return vo;
    }
    
    /**
     * 转换为Entity
     */
    private Shop convertToEntity(ShopDTO dto) {
        if (dto == null) {
            return null;
        }
        Shop entity = new Shop();
        BeanUtils.copyProperties(dto, entity);
        
        // 处理图片信息，使用FileInfoDTO格式存储完整的文件信息
        if (dto.getImages() != null && !dto.getImages().isEmpty()) {
            entity.setImageInfoList(dto.getImages());
        }
        
        return entity;
    }
    
    /**
     * 转换为Entity（用于更新，排除shopCode字段）
     */
    private Shop convertToEntityForUpdate(ShopDTO dto) {
        if (dto == null) {
            return null;
        }
        Shop entity = new Shop();
        
        // 手动设置字段，排除shopCode
        entity.setId(dto.getId());
        entity.setShopName(dto.getShopName());
        // shopCode不设置，保持原有值
        entity.setShopType(dto.getShopType());
        entity.setCommunityId(dto.getCommunityId());
        entity.setBuildingId(dto.getBuildingId());
        entity.setUnitId(dto.getUnitId());
        entity.setRoomNumber(dto.getRoomNumber());
        entity.setFloorNumber(dto.getFloorNumber());
        entity.setArea(dto.getArea());
        entity.setRentPrice(dto.getRentPrice());
        entity.setContactPerson(dto.getContactPerson());
        entity.setContactPhone(dto.getContactPhone());
        entity.setBusinessLicense(dto.getBusinessLicense());
        entity.setStatus(dto.getStatus());
        entity.setRemark(dto.getRemark());
        
        // 处理图片信息，使用FileInfoDTO格式存储完整的文件信息
        if (dto.getImages() != null && !dto.getImages().isEmpty()) {
            entity.setImageInfoList(dto.getImages());
        }
        
        return entity;
    }
    
    /**
     * 处理图片信息，将imageInfo JSON字符串转换为图片相关字段
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》的异常处理规范
     */
    private void processImageInfo(ShopVO shopVO) {
        if (shopVO == null) {
            log.warn("处理店铺图片信息失败：shopVO为null");
            return;
        }
        
        try {
            // 解析imageInfo JSON字符串
            if (shopVO.getImageInfo() != null && !shopVO.getImageInfo().trim().isEmpty()) {
                List<FileInfoDTO> imageInfoList = FileInfoUtils.fromJsonString(shopVO.getImageInfo());
                
                // 安全检查：确保imageInfoList不为null
                if (imageInfoList == null) {
                    log.warn("解析店铺图片信息失败：imageInfoList为null，shopId: {}, imageInfo: {}", 
                            shopVO.getId(), shopVO.getImageInfo());
                    setDefaultImageInfo(shopVO);
                    return;
                }
                
                shopVO.setImageInfoList(imageInfoList);
                
                // 提取图片URL列表 - 添加null安全检查
                List<String> imageUrls = imageInfoList.stream()
                    .filter(Objects::nonNull) // 过滤null对象
                    .map(FileInfoDTO::getFileUrl)
                    .filter(url -> url != null && !url.trim().isEmpty())
                    .collect(Collectors.toList());
                shopVO.setImageUrls(imageUrls);
                
                // 设置第一张图片URL
                if (!imageUrls.isEmpty()) {
                    shopVO.setFirstImageUrl(imageUrls.get(0));
                }
                
                // 设置图片数量
                shopVO.setImageCount(imageInfoList.size());
            } else {
                // 如果没有图片信息，设置默认值
                setDefaultImageInfo(shopVO);
            }
        } catch (Exception e) {
            log.error("处理店铺图片信息失败，shopId: {}, imageInfo: {}", 
                    shopVO.getId(), shopVO.getImageInfo(), e);
            // 设置默认值
            setDefaultImageInfo(shopVO);
        }
    }
    
    /**
     * 设置默认图片信息
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》的代码复用原则
     */
    private void setDefaultImageInfo(ShopVO shopVO) {
        if (shopVO == null) {
            return;
        }
        shopVO.setImageInfoList(new ArrayList<>());
        shopVO.setImageUrls(new ArrayList<>());
        shopVO.setFirstImageUrl(null);
        shopVO.setImageCount(0);
    }
}